/**
 * 洋葱圈模型 koa async await
 *
 * 1. js是单线程语言 但是js运行的环境不是单线程 （web环境 / node环境）
 * [调用栈] 先执行 同步任务 ---->  执行微任务队列 --->  执行宏任务队列
 *
 * 后进先出 ---> 调用栈   1 2 3 4  （4 3 2 1）
 * 先进先出 ---> 队列
 *
 * 任务队列---> 区分宏任务 微任务 --> 异步任务
 * [宏任务]  setTimeout-callback
 * [微任务]  1 - 2 - 3 - 4
 *
 *
 * 1： 而异步任务的执行，首先它依旧会进入调用栈中，然后发起调用，然后解释器会将其响应回调任务放入一个任务队列,紧接着调用栈会将这个任务移除
 * 2: 当主线程清空后，即所有同步任务结束后，解释器会读取任务队列，并依次将已完成的异步任务加入调用栈中并执行。
 * 3. 而不同的线程就会对不同的事件进行处理，当对应事件可以执行的时候，对应线程就会将其放入任务队列。
 *
 *  互斥线程
 *   - js引擎线程：用于解释执行js代码、用户输入、网络请求等；script (v8)
     - GUI渲染线程：绘制用户界面，与JS主线程互斥（因为js可以操作DOM，进而会影响到GUI的渲染结果）；

    - http异步网络请求线程：处理用户的get、post等请求，等返回结果后将回调函数推入到任务队列；
    - 定时触发器线程：setInterval、setTimeout等待时间结束后，会把执行函数推入任务队列中；
    - 浏览器事件处理线程：将click、mouse等UI交互事件发生后，将要执行的回调函数放入到事件队列中。
 *
 *
 * [事件循环 Event Loop] 如何排队
 *
·当我们第一次执行的时候，解释器会将整体代码script放入宏任务队列中，因此事件循环是从第一个宏任务开始的；
·如果在执行微任务的过程中，产生新的微任务添加到微任务队列中，也需要一起清空；微任务队列没清空之前，是不会执行下一个宏任务的。
 *
 *
 *
 * 执行代码：
 *
 * 调用栈  ---> : 执行代码
 *
 * 任务队列：
 *  1. 宏任务队列 ---> run script -> 定时器() 动画
 *  2. 微任务队列 ---> promise.then / .catch / .finally / mutaionobserver
 *
 *
 * async世界：
 *
 * 1. async关键字是将一个同步函数变成一个异步函数，并将返回值变为promise：
 * 2. await可以放在任何异步的、基于promise的函数之前 （还能放置普通执行函数）：
 *   它会暂停代码在该行上；（阻塞）
 * 3. 而在暂停的同时，其他正在等待执行的代码就有机会执行了。
 * 4. await后面。当成微任务执行
 *
 *
 *
 */

/**
 * 代码执行顺序：
 *
 * 调用栈：
 * 1. console.log("d"); // d  --->  出栈
 * 2. settimeout              --->  出栈
 * 3. async 1函数执行上下文入栈
 * 4. console.log("a"); // a  --->  出
 * 5. async 2入栈  async1-出栈
 * 6. console.log("c"); // c --->  出
 *    async1 重新入栈
 * 7. async2 -------------------> 出栈 await阻塞消失
 * 8. console.log("b"); // b ---> 出栈
 *
 *
 *
 * 宏任务：
 *  1. setTimeout-callback
 * 微任务：
 *
 *
 * 解析过程：
 *
 * run script ---> 同步任务
 *
 *
 *
 */

/**
 *
 * 函数执行：
 *
 * 1. 调用栈
  *   myAsync1 --->
  *   console.log(1) --->
  *   console.log(2) --->
  *   console.log(3) --->
  *   console.log(4) --->
 *    myAsync3
 *    console.log('2-end')
 *    console.log('1-end')
 * 2. 宏任务
 *   setTimeout-callback
 * 3. 微任务
 *  console.log('3-end') 1
 *  console.log(5)       2
 *
 *
 *  // 1 2 3 4 3-end --> 5 ---> 2-end ---> 1-end; 微任务结束之后，一个事件循环就结束了
 *
 * 下一个事件循环，同步 -- 微 --- 宏任务
 *
 *
 *  同 - 微 - 宏
 *  await 之后 微
 *
 *
 * 最后一个知识点：
 *  数据结构：
 *
 *
*/



/***
 *
 *   event loop:
 * 一、js单线程（为什么，在哪儿单？怎么用多？）
 * 二、同步异步（什么是？异步包含什么？）
 * 三、异步队列（宏任务队列/微任务队列--宏任务/微任务）
 *
 * 四、await阻塞之后，会让当前函数 跳出执行栈
 *
 * 五、await之后，是一个微任务 （）
 *
 * 六、涉及到三个主体：
 *   [调用栈]  --->
 *   [队列-宏任务]
 *   [队列-微任务]
 *
 * 七：数据结构：
 *    栈结构 ： 先进后出  （路由）
 *    队列   ： 先进先出（）
 *
 *  （数据结构之-队列的种类）：
 *    1. 击鼓传花
 *    2. 回文判断 （）
 *
 *  set
 *   weakset
 *  map
 *   weakmap
 *
 *
 *
 */


setTimeout(() => {
  console.log(7)
}, 0)

const myAsync1 = async function() {
   console.log(1)
   await myAsync2()
   console.log('1-end')
}
const myAsync2 = async function() {
  console.log(2)
  await myAsync3()
  console.log('2-end')
}
const myAsync3 = async function() {
  await console.log(3)
  console.log('3-end')
}
//
myAsync1()

new Promise((resolve, reject) => {
  console.log(4)
  resolve()
}).then(res => {
  console.log(5)
})
